<!doctype html>
<!--
  Copyright (c) 2015-present, Facebook, Inc.
  All rights reserved.

  This source code is licensed under the BSD-style license found in the
  LICENSE file in the root directory of this source tree. An additional grant
  of patent rights can be found in the PATENTS file in the same directory.
-->

<html>
<head>
<meta charset=utf-8>
<!-- Fake favicon, to avoid extra request to server -->
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<title>React Native Debugger</title>
<script>
(function() {

var sessionID = window.localStorage.getItem('sessionID');
window.localStorage.removeItem('sessionID');

window.onbeforeunload = function() {
  if (sessionID) {
    return 'If you reload this page, it is going to break the debugging session. ' +
      'You should press ⌘R in simulator to reload.';
  }
};

window.addEventListener('load', function () {
  if (typeof window.__REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
    document.getElementById('devtools-banner').style.display = 'block';
  }
});

// Alias native implementations needed by the debugger before platform-specific
// implementations are loaded into the global namespace
var debuggerSetTimeout = window.setTimeout;
var DebuggerWebSocket = window.WebSocket;

function setStatus(status) {
  document.getElementById('status').innerHTML = status;
}

// This worker will run the application javascript code,
// making sure that it's run in an environment without a global
// document, to make it consistent with the JSC executor environment.
var worker = new Worker('debuggerWorker.js');

var messageHandlers = {
  // This method is a bit hacky. Catalyst asks for a new clean JS runtime.
  // The easiest way to do this is to reload this page. That also means that
  // web socket connection will be lost. To send reply back we need to remember
  // message id.
  // This message also needs to be handled outside of the worker, since the worker
  // doesn't have access to local storage.
  'prepareJSRuntime': function(message) {
    window.onbeforeunload = undefined;
    window.localStorage.setItem('sessionID', message.id);
    window.location.reload();
  },
  'executeApplicationScript': function(message) {
    worker.postMessage(message);
  },
  'executeJSCall': function(message) {
    worker.postMessage(message);
  }
};

function connectToDebuggerProxy() {
  var ws = new DebuggerWebSocket('ws://' + window.location.host + '/debugger-proxy');

  ws.onopen = function() {
    if (sessionID) {
      setStatus('Debugger session #' + sessionID + ' active.');
      ws.send(JSON.stringify({replyID: parseInt(sessionID, 10)}));
    } else {
      setStatus('Waiting, press <span class="shortcut">⌘R</span> in simulator to reload and connect.');
    }
  };

  ws.onmessage = function(message) {
    var object = JSON.parse(message.data);
    if (!object.method) {
      return;
    }

    var handler = messageHandlers[object.method];
    if (handler) {
      handler(object);
    } else {
      console.warn('Unknown method: ' + object.method);
    }
  };

  ws.onclose = function() {
    setStatus('Disconnected from proxy. Attempting reconnection. Is node server running?');

    sessionID = null;
    window.localStorage.removeItem('sessionID');
    debuggerSetTimeout(connectToDebuggerProxy, 100);
  };

  worker.onmessage = function(message) {
    ws.send(JSON.stringify(message.data));
  }
}

connectToDebuggerProxy();

})();
</script>
<style type="text/css">
  body {
    font-size: large;
    margin: 0;
    padding: 0;
    font-family: Helvetica, Verdana, sans-serif;
    font-weight: 200;
  }
  .shortcut {
    font-family: "Monaco", monospace;
    font-size: medium;
    color: #eee;
    background-color: #333;
    padding: 4px;
    border-radius: 4px;
    letter-spacing: 3px;
  }
  #devtools-banner {
    display: none;
    background-color: #FDFDD5;
    padding: 10px;
  }
  #devtools-banner h3 {
    margin: 0;
    font-weight: normal;
  }
  #devtools-banner a {
    display: none;
    padding: 10px 20px 10px 20px;
    margin-bottom: 10px;
    color: white;
    text-decoration: none;
    font-size: 11px;
    text-shadow: 0 1px 1px rgba(0,0,0,0.1);
    text-transform: uppercase;
    font-weight: bold;
    background-color: #4d7bd6;
    border-radius: 2px;
    border: 1px solid #2d53af;
    display: inline-block;
  }
  .content {
    padding: 10px;
  }
</style>
</head>
<body>
  <div id="devtools-banner">
    <h3>Install React DevTools</h3>
    <p>
       React Developer Tools is an extension that allows you to inspect the
       React component hierarchies in the Chrome Developer Tools.
    </p>
    <a href="https://fb.me/react-devtools" target="_blank">
      Install
    </a>
  </div>
  <div class="content">
    <p>
      React Native JS code runs inside this Chrome tab.
    </p>
    <p>Press <span class="shortcut">⌘⌥J</span> to open Developer Tools. Enable <a href="http://stackoverflow.com/a/17324511/232122" target="_blank">Pause On Caught Exceptions</a> for a better debugging experience.</p>
    <p>Status: <span id="status">Loading...</span></p>
  </div>
</body>
</html>
